--- 战斗主类
---
--- @class TargetRuleSelector
TargetRuleSelector = ClientFight.CreateClass("TargetRuleSelector")
local this = TargetRuleSelector

--- @public
--- @return TargetRuleSelector
function TargetRuleSelector:ctor()
    self.map = {}
    --距离较近 */
    this:initMap(1, "距离较近", function(fighter, targetFighters, targetRuleParam)

        table.sort(targetFighters,function(fighter1, fighter2)

            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if distanceSquared1 ~= distanceSquared2 then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector0 =  self.map[1];
    --血量较低 */
    this:initMap(2, "血量较低", function(fighter, targetFighters, targetRuleParam)


        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = fighter1.hp;
            local value2 = fighter2.hp;
            if value1 ~= value2 then
                return value1 <= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end)
        return targetFighters;

    end)
    self.selector2 =  self.map[2];

    --距离较远 */
    this:initMap(3, "距离较远", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if distanceSquared1 ~= distanceSquared2 then
                return distanceSquared1 >= distanceSquared2 or false  or true ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector3 =  self.map[3];


    --随机目标 */
    this:initMap(5, "随机目标", function(fighter, targetFighters, targetRuleParam)
        return Table_Rand(targetFighters);
    end)
    self.selector5 =  self.map[5];


    --角度较小 */
    this:initMap(6, "角度较小", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local angle1 = 1.7976931348623157E308;
            if (fighter.position.x ~= fighter1.position.x) then
                angle1 = math.abs(fighter.position.y - fighter1.position.y) / math.abs(fighter.position.x - fighter1.position.x);
            end
            local angle2 = 1.7976931348623157E308;
            if (fighter.position.x ~= fighter2.position.x) then
                angle2 = math.abs(fighter.position.y - fighter2.position.y) / math.abs(fighter.position.x - fighter2.position.x);
            end
            return angle1 <= angle2  ;
        end);
        return targetFighters;

    end)
    self.selector6 =  self.map[6];

    --攻击较高 */
    this:initMap(7, "攻击较高", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)

            local value1 = FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.ATK);
            local value2 = FighterAttributeManager.getFightAttr(fighter2, FighterAttributeEnum.ATK);
            if (value1 ~= value2) then
                return value1 >= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector7 =  self.map[7];


    --远战优先 */
    this:initMap(8, "远战优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1.isRangedCLass() ~= fighter2.isRangedCLass()) then
                return fighter1.isRangedCLass()  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector8 =  self.map[8];


    --血量比 较低（较虚弱） */

    this:initMap(9, "血量比 较低", function(fighter, targetFighters, targetRuleParam)

        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = fighter1.hp / FighterAttributeManager.getFightAttr(fighter1, ClientFight.FighterAttributeEnum.HP);
            local value2 = fighter2.hp / FighterAttributeManager.getFightAttr(fighter2, ClientFight.FighterAttributeEnum.HP);
            if (value1 ~= value2) then
                return value1 <= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector9 =  self.map[9];

    --能量较低 */
    this:initMap(10, "能量较低", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1.energy ~= fighter2.energy) then
                return fighter1.energy <= fighter2.energy  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector10 =  self.map[10];

    --防御较低 */
    this:initMap(12, "防御较低", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.DEF);
            local value2 = FighterAttributeManager.getFightAttr(fighter2, FighterAttributeEnum.DEF);
            if (value1 ~= value2) then
                return value1 <= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector12 =  self.map[12];

    --近战优先 */
    this:initMap(13, "近战优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1.isRangedCLass() ~= fighter2.isRangedCLass()) then
                return not fighter1.isRangedCLass()  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector13 =  self.map[13];

    --防御较高 */
    this:initMap(14, "防御较高", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.DEF);
            local value2 = FighterAttributeManager.getFightAttr(fighter2, FighterAttributeEnum.DEF);
            if (value1 ~= value2) then
                return value1 >= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector14 =  self.map[14];

    --对位目标 */
    this:initMap(15, "对位目标", function(fighter, targetFighters, targetRuleParam)
        local target = nil;
        for i = 1 ,  5 do
            local site = fighter.site + i;
            if (site > 5) then
                site = site - 5;
            end
            target = FighterUtils.getFighterBySite(targetFighters, site);
            if (target ~= nil) then
                break ;
            end
        end

        targetFighters = {};
        if (target ~= nil) then
            table.insert(targetFighters,target);
        end
        return targetFighters;
    end)
    self.selector15 =  self.map[15];

    --能量较高 */
    this:initMap(16, "能量较高", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1.energy ~= fighter2.energy) then
                return fighter1.energy >= fighter2.energy  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector16=  self.map[16];
    --战场中心距离较远 */
    this:initMap(17, "战场中心距离较远", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local distanceSquared1 = DistanceUtil.countDistanceSquared(Global.FIGHT_CENTER_POSITION, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(Global.FIGHT_CENTER_POSITION, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 >= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector17 =  self.map[17];

    --魔抗较低 */
    this:initMap(18, "魔抗较低", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.MAGIC_DAMAGE);
            local value2 = FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.MAGIC_DAMAGE);
            if (value1 ~= value2) then
                return value1 <= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector18 =  self.map[18];

    --后排优先 */
    this:initMap(19, "后排优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1:isFrontRow() ~= fighter2:isFrontRow()) then
                return not fighter1:isFrontRow()  ;
            end

            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector19 =  self.map[19];
    --前排优先 */
    this:initMap(20, "前排优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1:isFrontRow() ~= fighter2:isFrontRow()) then
                return fighter1:isFrontRow()  ;
            end
            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector20 =  self.map[20];

    --魔法攻击者优先 */
    this:initMap(21, "魔法攻击者优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            if (fighter1.normalAttack == nil) then
                return true ;
            end
            if (fighter2.normalAttack == nil) then
                return false ;
            end

            local value1 = fighter1.normalAttack.skillBean.f_HurtMethod;
            if (value1 == 2) then
                return false ;
            end

            return true ;
        end);
        return targetFighters;
    end)
    self.selector21 =  self.map[21];

    --使用主人最后普攻的目标 */
    this:initMap(23, "使用主人最后普攻的目标", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        if (fighter.summonsCreater ~= nil) then
            local lastNormalAttackFighter = fighter.summonsCreater.lastNormalAttackFighter;
            if (lastNormalAttackFighter ~= nil and not lastNormalAttackFighter:isDie()) then
                table.insert(list, lastNormalAttackFighter);
            end
        end
        return list;


    end)
    self.selector23 =  self.map[23];
    --暴击较高 */
    this:initMap(24, "暴击较高", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.CRITRATE);
            local value2 = FighterAttributeManager.getFightAttr(fighter2, FighterAttributeEnum.CRITRATE);
            if (value1 ~= value2) then
                return value1 >= value2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector23 =  self.map[23];

    --距离较近（优选队友，没有则自己） */
    this:initMap(25, "距离较近（优选队友，没有则自己）", function(fighter, targetFighters, targetRuleParam)
        if (table.getn(targetFighters) > 0 ) then
            table.sort(targetFighters,function(fighter1, fighter2)
                local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
                local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
                if (distanceSquared1 ~= distanceSquared2) then
                    return distanceSquared1 <= distanceSquared2  ;
                end
                return fighter1.fighterId < fighter2.fighterId;
            end);
            return targetFighters;
        end

        local fighters = {};
        table.insert(fighters, fighter);
        return fighters;
    end)
    self.selector25 =  self.map[25];

    --远战 */
    this:initMap(26, "远战", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do
            if (f.isRangedCLass()) then
                table.insert(list, f);
            end
        end
        return list;
    end)
    self.selector26 =  self.map[26];

    --近战 */
    this:initMap(27, "近战", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do

            if (not f.isRangedCLass()) then
                table.insert(list, f);
            end
        end
        return list;
    end)
    self.selector27 =  self.map[27];

    --前排 */
    this:initMap(28, "前排", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do

            if (f:isFrontRow()) then
                table.insert(list,f);
            end
        end
        return list;
    end)
    self.selector28 =  self.map[28];
    --后排 */
    this:initMap(29, "后排", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do

            if (not f:isFrontRow()) then
                table.insert(list, f);
            end
        end
        return list;
    end)
    self.selector29 =  self.map[29];

    --法师 */
    this:initMap(30, "法师", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do

            if (f.heroBean.f_HeroType == HeroConst.Hero_Type_MO_DAO_SHI) then
                table.insert(list,f);
            end
        end
        return list;
    end)
    self.selector30 =  self.map[30];
    --自己和自己的召唤物 */
    this:initMap(31, "自己和自己的召唤物", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do
            if (not f:isDie()) then
                if (f == fighter or f.summonsCreater == fighter) then
                    table.insert(list, f);
                end
            end
            return list;
        end
    end)
    self.selector31 =  self.map[31];

    --替补 */
    this:initMap(32, "替补", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        for i, f in pairs(targetFighters) do
            if (not f:isDie() and f:isAssistant()) then
                table.insert(list, f);
            end
        end
        return list;
    end)
    self.selector32 =  self.map[32];

    --敌方半场,战场中心为界,敌方半场 */
    this:initMap(33, "敌方半场", function(fighter, targetFighters, targetRuleParam)
        local list = {};
        local direction = FighterUtils.getTeamSiteDirection(fighter);
        local centerX = Global.FIGHT_CENTER_POSITION.x;
        for i, f in pairs(targetFighters) do
            local isAdd = true
            if (f:isDie()) then
                isAdd = false;
            end
            if (direction == Global.RIGHT) then
                --我朝向右边
                if (f.position.x < centerX) then
                    isAdd = false
                end
            else
                if (f.position.x > centerX) then
                    isAdd = false;
                end
            end
            if isAdd then
                list.add(f);
            end
        end
        return list;
    end)
    self.selector33 =  self.map[33];
    --受我方伤害最多的敌人 */
    this:initMap(34, "受我方伤害最多的敌人", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local beInjured = fighter1.fighterStats.beInjured;
            local beInjured2 = fighter2.fighterStats.beInjured;
            if (beInjured ~= beInjured2) then
                return beInjured <= beInjured2 and true  or false ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector34 =  self.map[34];
    --输出最高的敌人 */
    this:initMap(35, "输出最高的敌人", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local beInjured = fighter1.fighterStats.attack;
            local beInjured2 = fighter2.fighterStats.attack;
            if (beInjured ~= beInjured2) then
                return beInjured <= beInjured2 and true  or false ;
            end

            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector35 =  self.map[35];
    --受我方最多单位攻击的敌人 */
    this:initMap(36, "受我方最多单位攻击的敌人", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local beInjured = table.getn(fighter1.fighterStats.attackerMe);
            local beInjured2 = table.getn(fighter2.fighterStats.attackerMe);
            if (beInjured ~= beInjured2) then
                return beInjured2 - beInjured;
            end

            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector36 =  self.map[36];
    --血量比 较高（） */
    this:initMap(37, "血量比 较高", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = fighter1.hp / FighterAttributeManager.getFightAttr(fighter1, FighterAttributeEnum.HP);
            local value2 = fighter2.hp / FighterAttributeManager.getFightAttr(fighter2, FighterAttributeEnum.HP);
            if (value1 ~= value2) then
                return value1 <= value2 and true  or false ;
            end

            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector37 =  self.map[37];
    --含有指定标记的（） */
    this:initMap(38, "含有指定标记的", function(fighter, targetFighters, targetRuleParam)
        if (targetRuleParam == nil or table.getn(targetRuleParam) < true ) then
            return targetFighters;
        end
        local tag = targetRuleParam[1];
        table.sort(targetFighters,function(fighter1, fighter2)
            local v1 = fighter1.totalSign.signs[tag] and 0 or true ;
            local v2 = fighter2.totalSign.signs[tag] and 0 or true ;
            if (v1 ~= v2) then
                return v1 - v2;
            end
            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector38 =  self.map[38];
    --召唤物优先（） */
    this:initMap(39, "召唤物优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local v1 = fighter1.summons and 0 or true ;
            local v2 = fighter2.summons and 0 or true ;
            if (v1 ~= v2) then
                return v1 - v2;
            end
            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector39 =  self.map[39];
    --英雄优先（） */
    this:initMap(40, "英雄优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local v1 = fighter1.summons and true  or 0;
            local v2 = fighter2.summons and true  or 0;
            if (v1 ~= v2) then
                return v1 - v2;
            end
            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector40 =  self.map[40];
    --有护盾的优先（） */
    this:initMap(41, "有护盾的优先", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local v1 = fighter1.defeatPool;
            local v2 = fighter2.defeatPool;
            if (v1 ~= v2) then
                return v2 > v1 and true  or false ;
            end
            local distanceSquared1 = DistanceUtil.countDistanceSquared(fighter.position, fighter1.position);
            local distanceSquared2 = DistanceUtil.countDistanceSquared(fighter.position, fighter2.position);
            if (distanceSquared1 ~= distanceSquared2) then
                return distanceSquared1 <= distanceSquared2  ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector41 =  self.map[41];

    --血量较高 */
    this:initMap(42, "血量较高", function(fighter, targetFighters, targetRuleParam)
        table.sort(targetFighters,function(fighter1, fighter2)
            local value1 = fighter1.hp;
            local value2 = fighter2.hp;
            if (value1 ~= value2) then
                return value1 <= value2 and true  or false ;
            end
            return fighter1.fighterId < fighter2.fighterId;
        end);
        return targetFighters;
    end)
    self.selector42 =  self.map[42];

end


function this:valueOf(id)
    return self.map[id];
end
function this:initMap(id, name, func)
    local obj = {}
    obj.id = id;
    obj.name = name .. "[" .. id .. "]";
    obj.action = func;
    function obj:getId()
        return id;
    end

    function obj:getName()
        return name;
    end
    self.map[id] = obj;
end
function this:action(fighter, targetRule, fighters, targetRuleParam)
    local targetRuleSelector = this:valueOf(targetRule)
    if (targetRuleSelector ~= nil) then
        fighters = targetRuleSelector.action(fighter, fighters, targetRuleParam);
    end
    return fighters;
end
TargetRuleSelector:ctor()